package com.whut.util.concurrent.locks;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author wangzonghe
 * @date 2025/8/8 11:00
 */
public abstract class BaseLock implements Lock {

    private static final Logger log = LoggerFactory.getLogger(BaseLock.class);

    /**
     * 非公平锁
     * 获取失败会进行阻塞，加入阻塞队列，直到获取到锁
     */
    public void lock() {
        lockUnfair();
    }

    public void unReentrantLock() {
        unReentrantLockUnFair();
    }

    /**
     * 自定义是否公平锁
     * 获取失败会进行阻塞，加入阻塞队列，直到获取到锁
     *
     * @param isFair 是否公平锁
     */
    public void lock(boolean isFair) {
        if (isFair) {
            lockFair();
        } else {
            lockUnfair();
        }
    }

    /**
     * 尝试获取锁，如果获取失败，则等待timeUnit.tiMillis(time)ms后再次尝试获取锁，尝试tryCount次
     *
     * @param tryCount 尝试次数
     * @param time     重试间隔时间
     * @param timeUnit 时间单位
     * @return 是否成功获取锁
     */
    public boolean tryLock(int tryCount, long time, TimeUnit timeUnit) {
        if (tryCount <= 0 || time <= 0) {
            return false;
        }
        long millis = timeUnit.toMillis(time);
        int i = 1;
        while (tryCount > 0) {
            if (tryLock()) {
                log.info("线程{}获取锁成功", Thread.currentThread().getName());
                return true;
            }
            log.info("线程{}第{}次获取锁失败，正在重试...", Thread.currentThread().getName(), i++);
            tryCount--;
            long deadLine = System.currentTimeMillis() + millis;

            // 预防虚假唤醒
            while (System.currentTimeMillis() < deadLine) {
                LockSupport.parkUntil(deadLine);
            }
        }
        return false;
    }

}
